package com.ordertracker.endpoint;

import com.ordertracker.Application;
import com.ordertracker.client.ClientSession;
import com.ordertracker.entity.User;
import com.ordertracker.exception.ConversionException;
import com.ordertracker.exception.NotAuthorizationException;
import com.ordertracker.exception.ValidationException;
import com.ordertracker.protocol.CommandMessage;
import com.ordertracker.protocol.UserFullInfo;
import com.ordertracker.protocol.RequestAuthorization;
import com.ordertracker.protocol.ResponseAuthorization;
import com.ordertracker.security.ApplicationSecurityContext;
import com.ordertracker.service.AuthorizationService;
import com.ordertracker.service.UserManager;
import com.sun.jersey.spi.container.ContainerRequest;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;
import javax.xml.bind.JAXBException;
import java.io.StringReader;


@Component
@Path("/accounts")
public class AccountEndPoint {


    private AuthorizationService service;
    private UserManager userManager;


    @Resource(name = "authorizationService")
    public void setService(AuthorizationService service) {
        this.service = service;
    }

    @Resource(name = "user")
    public void setUserManager(UserManager userManager) {
        this.userManager = userManager;
    }

    @POST
    @Path("/login")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response login(RequestAuthorization requestAuthorization) {
        ResponseAuthorization response = null;
        try {
            response = service.checkUser(requestAuthorization.getLogin(),requestAuthorization.getPassword(),
                    requestAuthorization.getLocale(), requestAuthorization.getTimezone());
            return Response.status(201).entity(response).build();
        } catch (NotAuthorizationException e) {
            return Response.status(Response.Status.UNAUTHORIZED).build();
        }
    }

    @POST
    @Path("/logout")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response logout(ClientSession clientSession) {
        service.logout(clientSession);
        return Response.status(Response.Status.MOVED_PERMANENTLY).build();
    }

    @POST
    @Path("/add")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response addUser(@Context Request request, CommandMessage msg) {
        ApplicationSecurityContext securityContext = (ApplicationSecurityContext)(((ContainerRequest) request).getSecurityContext());
        UserFullInfo createNewUser = null;
        try {
            createNewUser = Application.getApplication().getJsonUnmarshaller().unmarshalFromJSON(new StringReader(msg.getObj()), UserFullInfo.class);
        } catch (JAXBException e) {
            throw new ConversionException(e, Response.status(Response.Status.BAD_REQUEST).build());
        }

        UserFullInfo user = userManager.createUser(securityContext.getSession(), createNewUser);
        return Response.ok(user).build();
    }

    @GET
    @Path("/user_full_info/{id}")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response getUserFullInfoByID(@Context Request request, @PathParam("id") Long id) {
        ApplicationSecurityContext securityContext = (ApplicationSecurityContext)(((ContainerRequest) request).getSecurityContext());
        if (null == id) {
            throw new ValidationException("Parameter ID must be not null", Response.status(Response.Status.BAD_REQUEST).build());
        }

        UserFullInfo user = userManager.getUserFullInfoByID(id);
        return Response.ok(user).build();
    }

    @GET
    @Path("/get/{id}")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response getUserByID(@Context Request request, @PathParam("id") Long id) {
        ApplicationSecurityContext securityContext = (ApplicationSecurityContext)(((ContainerRequest) request).getSecurityContext());
        if (null == id) {
            throw new ValidationException("Parameter ID must be not null", Response.status(Response.Status.BAD_REQUEST).build());
        }

        User user = userManager.getUser(id);
        return Response.ok(user).build();
    }

}
